﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Drawing;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using Common.Logging;
using Jackie.Utility.Notify.Contracts;
using Jackie.Utility.Notify.Domain;

namespace Jackie.Utility.Notify.Client
{
    public partial class MessageForm : Form
    {
        private DuplexChannelFactory<ISubscribe> subscribeChannel;
        private ISubscribe subscribeClient;

        private MessageProcesser messageProcesser;
        private ILog logger;

        private IDictionary<string, RichTextBox> messageContainers;


        public MessageForm()
        {
            InitializeComponent();
            logger = LogManager.GetLogger(GetType());
            try
            {
                messageProcesser = new MessageProcesser();
                messageProcesser.MessageArrived += new MessageArrivedHandler(MessageProcesser_MessageArrived);
                var instance = new InstanceContext(messageProcesser);
                subscribeChannel = new DuplexChannelFactory<ISubscribe>(instance, "SubscribService");
                subscribeClient = subscribeChannel.CreateChannel();

                messageContainers = new Dictionary<string, RichTextBox>();
                this.Load += new EventHandler(MessageForm_Load);

                this.Shown += new EventHandler(MessageForm_Shown);

                this.Closing += new CancelEventHandler(MessageForm_Closing);

            }
            catch (Exception ex)
            {
                logger.Error("error!", ex);
            }
        }

        void MessageForm_Shown(object sender, EventArgs e)
        {
            logger.Info("start to subscrible message title!");
            var codes = ConfigurationManager.AppSettings["listenCodes"].Split(',');
            var clientSign = ConfigurationManager.AppSettings["clientSign"];
            foreach (var code in codes)
            {
                subscribeClient.Subscribe(clientSign, code);
                logger.Info("subscribled message title:" + code);
            }
            logger.Info("end of subscribtion!");
        }

        private void MessageForm_Load(object sender, EventArgs e)
        {
            RegisterListenControlsAndSubscribeTitle();
        }


        /// <summary>
        /// 注册消息显示控件和订阅配置的消息
        /// </summary>
        public void RegisterListenControlsAndSubscribeTitle()
        {
            var codes = ConfigurationManager.AppSettings["listenCodes"].Split(',');
            foreach (var code in codes)
            {
                var title = subscribeClient.Get(code);

                var tabMessage = new TabPage
                                     {
                                         Name = "tab" + code,
                                         Padding = new Padding(3),
                                         Text = title.Name,
                                         UseVisualStyleBackColor = true
                                     };

                var txtMessage = new RichTextBox
                                     {
                                         Dock = DockStyle.Fill,
                                         HideSelection = false,
                                         Name = "txt" + code,
                                         ReadOnly = true
                                     };
                messageContainers.Add(txtMessage.Name, txtMessage);

                var lblDiscription = new Label()
                                         {
                                             Dock = DockStyle.Bottom,
                                             Name = "lbl" + code,
                                             Text = "说明：" + title.Discription,
                                             Padding = new Padding(3),
                                             Height = 35
                                         };

                tabMessage.Controls.Add(txtMessage);
                tabMessage.Controls.Add(lblDiscription);

                tabMain.TabPages.Add(tabMessage);
            }
        }

        private void MessageProcesser_MessageArrived(object sender, MessageArrivedEventArgs e)
        {
            try
            {
                SetMessageText(e.Message);
            }
            catch (Exception ex)
            {
                logger.Error("error!", ex);
            }

        }

        private delegate void SetMessageTextHandler(MessageInfo message);

        private void SetMessageText(MessageInfo message)
        {
            var txtmessage = messageContainers["txt" + message.TitleCode];
            if (txtmessage.InvokeRequired)
            {
                var handler = new SetMessageTextHandler(SetMessageText);
                this.Invoke(handler, new object[] { message });
            }
            else
            {
                var showFormat = ConfigurationManager.AppSettings[message.TitleCode + "MessageFormat"];
                var sb = new StringBuilder(txtmessage.Text);
                var currentMessage = Environment.NewLine +
                                     string.Format(showFormat, message.Code, message.Message, message.ExtenderMessage);
                sb.Insert(0, currentMessage);
                txtmessage.Text = sb.ToString();
            }
        }

        private void MessageForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            if (subscribeChannel.State == CommunicationState.Opened)
                subscribeChannel.Close();
        }

        private void MessageForm_Resize(object sender, EventArgs e)
        {
            if (this.WindowState == FormWindowState.Minimized)
            {
                this.ShowInTaskbar = false;
            }
        }

        private void minSizeIcon_DoubleClick(object sender, EventArgs e)
        {
            if (this.WindowState == FormWindowState.Minimized)
            {
                this.WindowState = FormWindowState.Normal;
            }
            this.ShowInTaskbar = true;
        }

        private void tsmiExit_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        void MessageForm_Closing(object sender, CancelEventArgs e)
        {
            logger.Info("start to unsubscribe messages title");
            var codes = ConfigurationManager.AppSettings["listenCodes"].Split(',');
            var clientSign = ConfigurationManager.AppSettings["clientSign"];
            foreach (var code in codes)
            {
                subscribeClient.Unsubscribe(clientSign, code);
                logger.Info("unsubscribe messages title:" + code);
            }
            logger.Info("end unsubscribtion");
        }
    }
}
